package com.topisv.tms.rest.qimen.qmservice;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.xml.bind.JAXB;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.stock.instorage.InstorageBill;
import com.topisv.tms.entity.stock.instorage.InstorageCountItem;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillPre;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.stock.instorage.InstorageBillDao;
import com.topisv.tms.repository.stock.instorage.InstorageCountItemDao;
import com.topisv.tms.repository.stock.preInstorage.InstorageBillPreDao;
import com.topisv.tms.rest.qimen.qmentity.EntryOrder;
import com.topisv.tms.rest.qimen.qmentity.EntryOrderItem;
import com.topisv.tms.rest.qimen.qmentity.request.instoragebillquery.InstorageBillQuery;
import com.topisv.tms.rest.qimen.qmentity.response.instoragebillquery.InstorageBillQueryResult;
import com.topisv.tms.rest.qimen.request.RequestParams;
import com.topisv.tms.rest.qimen.response.ResponseParams;

@Component
@Transactional(readOnly=true)
public class InstorageBillQueryCommand {
	private static final Logger logger = LoggerFactory.getLogger(InstorageBillQueryCommand.class);
	@Autowired
	private InstorageBillPreDao instorageBillPreDao;
	@Autowired
	private InstorageBillDao instorageBillDao;
	@Autowired
	private InstorageCountItemDao instorageCountItemDao;
	@Autowired
	private EdiGoodsSkuDao ediGoodSkuDao;

	
	public ResponseParams execute(RequestParams params) {
		String stringXml = params.getRequestXml();
		InstorageBillQueryResult result = new InstorageBillQueryResult();
		//返回请求参数
		ResponseParams response = new ResponseParams();
		try {
			logger.info("入库查询"+stringXml);
			//解析xml
			InstorageBillQuery billQuery = JAXB.unmarshal(new StringReader(stringXml), InstorageBillQuery.class);
			
			
			EntryOrder entryOrder = new EntryOrder();
			EntryOrderItem orderItem = new EntryOrderItem();
			List<EntryOrderItem> itemList = new ArrayList<EntryOrderItem>();
			
			String entryOrderCode = billQuery.getEntryOrderCode();		//入库单编码
			String ownerCode = billQuery.getOwnerCode();			//货主编码
			String warehouseCode = billQuery.getWarehouseCode();	//入库仓库编码
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("customerOrderNo", entryOrderCode);
			map.put("customerCode", ownerCode);
			map.put("inwarehouseCode", warehouseCode);
			
			InstorageBill bill = findBillByWhere(map);
			InstorageBillPre billPre = findBillPreByWhere(map);
			if(bill!=null){
				entryOrder.setEntryOrderCode(billPre.getCustomerOrderNo());
				//入库单状态(NEW-未开始处理ACCEPT-仓库接单,INPROCESS-处理中,FULFILLED-收货完成,EXCEPTION-异常,
				//CANCELED-取消,CLOSED关闭REJECT-拒单CANCELEDFAIL-取消失败)（只传英文编码）
				//入库状态 （0:待登记 (调拨货品已出库，尚未入库) 1.入库登记 2.领取点收任务 3.点收完成 4.领取上架任务 5.上架完成 ）
				if("0".equals(bill.getStatus()))
				{
					entryOrder.setStatus("NEW");
				}
				else if("1".equals(bill.getStatus()))
				{
					entryOrder.setStatus("ACCEPT");
				}
				else if("2".equals(bill.getStatus()))
				{
					entryOrder.setStatus("INPROCESS");
				}
				else if("3".equals(bill.getStatus()))
				{
					entryOrder.setStatus("INPROCESS");
				}
				else if("4".equals(bill.getStatus()))
				{
					entryOrder.setStatus("INPROCESS");
				}
				else if("5".equals(bill.getStatus()))
				{
					entryOrder.setStatus("FULFILLED");
				}
				entryOrder.setOwnerCode(billPre.getCustomerCode());
				entryOrder.setWarehouseCode(billPre.getInwarehouseCode());
				entryOrder.setRemark(billPre.getRemark());
				
				List<InstorageCountItem> countItem = instorageCountItemDao.loadByBillCode(bill.getBillCode());
				for(InstorageCountItem item : countItem){
					orderItem.setReceiveQty(item.getUpNum());
					EdiGoodsSku sku = ediGoodSkuDao.findByCustomerCodeAndSku(bill.getCustomerCode(),item.getSku());
					orderItem.setItemCode(sku.getBar());
					itemList.add(orderItem);
				}
				logger.info("查询成功");
				result.setFlag("success");
				result.setCode("");
				result.setMessage("");
				result.setEntryOrder(entryOrder);
				result.setItem(itemList);
				StringWriter writer = new StringWriter();
				JAXB.marshal(result,writer);
				response.setResponseXml(writer.toString());
			}else{
				logger.info("没有此单");
				result.setFlag("failure");
				result.setCode("");
				result.setMessage("不存在改单");
			}
			
		} catch (Exception e) {
			logger.info("系统异常");
			result.setFlag("failure");
			result.setCode("");
			result.setMessage("系统异常");
		}
		StringWriter writer = new StringWriter();
		JAXB.marshal(result,writer);
		response.setResponseXml(writer.toString());
		return response;
	}
	
	
	public InstorageBillPre findBillPreByWhere(Map<String,Object> param){
		Specification<InstorageBillPre> spec = getBillPreWhereClause(param);
		InstorageBillPre billPre = this.instorageBillPreDao.findOne(spec);
		return billPre;
	}
	/**
	 * 封装查询
	 * @param param
	 * @return
	 */
	private Specification<InstorageBillPre> getBillPreWhereClause(final Map<String, Object> param) {
		return new Specification<InstorageBillPre>(){
			@Override
		    public Predicate toPredicate(Root<InstorageBillPre> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				  Predicate pre = cb.conjunction();
				  //customerOrderNo 入库单编码
			      String customerOrderNo=(String) param.get("customerOrderNo");
			      if(StringUtils.isNotEmpty(customerOrderNo)){
						pre.getExpressions().add(cb.equal(r.get("customerOrderNo"),customerOrderNo));
				  }
			      //customerCode	客户编码
			      String customerCode=(String) param.get("customerCode");
			      if(StringUtils.isNotEmpty(customerCode)){
						pre.getExpressions().add(cb.equal(r.get("customerCode"),customerCode));
				  }
			    //inwarehouseCode	入库仓库编码
			      String inwarehouseCode=(String) param.get("inwarehouseCode");
			      if(StringUtils.isNotEmpty(inwarehouseCode)){
						pre.getExpressions().add(cb.equal(r.get("inwarehouseCode"),inwarehouseCode));
				  }
			      return pre;
			}
		  };
	}
	
	
	public InstorageBill findBillByWhere(Map<String,Object> param){
		Specification<InstorageBill> spec = getBillWhereClause(param);
		InstorageBill billPre = this.instorageBillDao.findOne(spec);
		return billPre;
	}
	/**
	 * 封装查询
	 * @param param
	 * @return
	 */
	private Specification<InstorageBill> getBillWhereClause(final Map<String, Object> param) {
		return new Specification<InstorageBill>(){
			@Override
		    public Predicate toPredicate(Root<InstorageBill> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				  Predicate pre = cb.conjunction();
				  //inwarehouseCode	入库仓库编码
			      String inwarehouseCode=(String) param.get("inwarehouseCode");
			      if(StringUtils.isNotEmpty(inwarehouseCode)){
						pre.getExpressions().add(cb.equal(r.get("inwarehouseCode"),inwarehouseCode));
				  }
			      //customerCode	客户编码
			      String customerCode=(String) param.get("customerCode");
			      if(StringUtils.isNotEmpty(customerCode)){
						pre.getExpressions().add(cb.equal(r.get("customerCode"),customerCode));
				  }
			      return pre;
			}
		  };
	}
}
